package org.ourgrid.peer.business.requester;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.ourgrid.common.internal.IResponseTO;
import org.ourgrid.common.internal.response.LoggerResponseTO;
import org.ourgrid.common.internal.response.OperationSucceedResponseTO;
import org.ourgrid.common.spec.worker.WorkerSpec;
import org.ourgrid.common.statistics.control.WorkerControl;
import org.ourgrid.peer.business.controller.messages.PeerControlMessages;
import org.ourgrid.peer.request.SetWorkersRequestTO;



public class SetWorkersRequester extends AbstractRegisterWorkerRequester<SetWorkersRequestTO>{

	public List<IResponseTO> execute(SetWorkersRequestTO request) {
		
		List<IResponseTO> responses = new ArrayList<IResponseTO>();
		
		String senderPubKey  = request.getSenderPubKey();
		List<WorkerSpec> newWorkers = request.getNewWorkers();
		
		if (request.canComponentBeUsed()) {
			if(!request.isThisMyPublicKey()) {
				responses.add(new LoggerResponseTO(PeerControlMessages.getUnknownSenderSettingWorkersMessage(senderPubKey), LoggerResponseTO.WARN));
				
				return responses;
			}
			
			discardOldWorkers(responses, newWorkers, request);
			registerNewWorkers(responses, newWorkers, request.getMyUserAtServer());

			OperationSucceedResponseTO to = new OperationSucceedResponseTO();
			to.setClientAddress(request.getClientAddress());
			
			responses.add(to);
		}
		
		return responses;
	}
	
	private void registerNewWorkers(List<IResponseTO> responses, Collection<WorkerSpec> newWorkers, String myUserAtServer) {
		for ( WorkerSpec newWorkerSpec : newWorkers ) {
			registerNewWorker(responses, newWorkerSpec, myUserAtServer);
		}
	}
		
	private void discardOldWorkers(List<IResponseTO> responses, Collection<WorkerSpec> newWorkers, SetWorkersRequestTO request) {
		
		Collection<String> currentWorkersUserAtServer = WorkerControl.getInstance().getLocalWorkersUserAtServer(
				responses, request.getMyUserAtServer());
		
		for (String userAtServer : currentWorkersUserAtServer) {
			if (!doesWorkerContinues(userAtServer, newWorkers)) {
				RemoveWorkerRequester.removeWorker(responses, userAtServer);
			}
		}

	}
	
	private boolean doesWorkerContinues(String oldWorkerUserAtServer, Collection<WorkerSpec> newWorkers) {
			
		for (WorkerSpec newWorkerSpec : newWorkers) {
			if (newWorkerSpec.getServiceID().getContainerID().getUserAtServer().equals(oldWorkerUserAtServer)) {
				return true;
			}
		}
		
		return false;
	}
		
}
